import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;


/*Copyright  Feliks Rozenberg

                  Licensed under the Apache License, Version 2.0 (the "License");
                  you may not use this file except in compliance with the License.
                  You may obtain a copy of the License at

                      http://www.apache.org/licenses/LICENSE-2.0

                  Unless required by applicable law or agreed to in writing, software
                  distributed under the License is distributed on an "AS IS" BASIS,
                  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                  See the License for the specific language governing permissions and
                  limitations under the License.*/



public class LanguageGuesser 
  
{
  
  public static void main(String[] args)
  {
    String[] fileNames = {"slovak.txt", "bulgarian.txt", "czech.txt", "danish.txt", 
      "dutch.txt", "english.txt", "estonian.txt", "finnish.txt", "french.txt", 
      "german.txt", "greek.txt", "hungarian.txt", "italian.txt", "latvian.txt",
      "lithuanian.txt", "polish.txt", "portuguese.txt", "romanian.txt", "slovenian.txt",
      "spanish.txt", "swedish.txt"};   
    
    Scanner input = null;
    
    
    System.out.println("Please specify the n for your n-gram: ");
    Scanner keyboard = new Scanner(System.in);
    int n= keyboard.nextInt();
    
    for(String fileName: fileNames)
    {
      //reading the file
      try
      {
        input = new Scanner (new File(fileName), "UTF-8");
      }
      catch(FileNotFoundException e)
      {
        System.out.println("Could not open the file " + fileName);
        System.exit(0);
      }
      input.useDelimiter("\\Z");
      //storing the text as a string and then after removing whitespaces in an array
      String text = input.next();
      text = text.replaceAll("\\s+", " ");
      //the " character turned out to be problematic (was considered as end of input by read buffer) so I had to remove all its occurences
      //text = text.replaceAll("\\p{Punct}", "");
      double textLength= text.length();
      
      System.out.println("The program has just read the " +fileName + " file."  );
//         System.out.println("Please specify the n for your n-gram: ");
//         Scanner keyboard = new Scanner(System.in);
//         int n= keyboard.nextInt();
      List<Map<String, Double>> listOfMaps = new ArrayList<Map<String, Double>>();
      
      for(int i=0; i<n; i++)
      {
        HashMap<String, Double> hashMap = new HashMap<String, Double>();
        listOfMaps.add(i, hashMap);
      }
      //storing the ngrams in hashmaps contained in an arraylist where the index+1 corresponds to the n of the ngram
      double countUnigrams = 0.0;
      int k =1;
      for(int i=0; i<text.length();i++)
      {
        while(k!=n+1)
        {    
          if(i+k<text.length())
          {
            String n1gram = text.substring(i, i+k);
            if(n1gram.length()==1)
              countUnigrams++;
            if(!listOfMaps.get(k-1).containsKey(n1gram))
            {
              listOfMaps.get(k-1).put(n1gram, 1.0);
            }
            else
            {
              double count = listOfMaps.get(k-1).get(n1gram) + 1.0;
              listOfMaps.get(k-1).put(n1gram, count);
            }
            
          }
          k++;
        }
        k=1;
      }
      
      //writing the hashMap to the file
      String outputfileName = "prbs" +fileName;
      PrintWriter outputStream= null;
      try
      {
        outputStream = new PrintWriter(outputfileName);  
      }
      catch(FileNotFoundException e)
      {
        System.out.println("Could not open the file " + fileName);
        System.exit(0);
      }   
      
      for(int i=0; i<listOfMaps.size(); i++)
      {
        
        Set ref = listOfMaps.get(i).keySet();;
        Iterator it = ref.iterator();
        while (it.hasNext())
        {
          String nGramKey = (String)it.next();
          String context= " ";
          int contextIndex = 0;
     
          double prb= 0.0;
          if(nGramKey.length()>1)
          {
            context = nGramKey.substring(0, nGramKey.length()-1);
            contextIndex = i-1;
            //System.out.println("The key " +  nGramKey + " and the context" + context);
            prb = (listOfMaps.get(i).get(nGramKey)-0.5)/ (listOfMaps.get(contextIndex).get(context));
            outputStream.write(nGramKey + "\n" + 
                               prb + "\n"); 
          }
          //if we have a unigram then we divide by the total frequency of the unigrams
          else
          {
            //System.out.println("The key " +  nGramKey + " and the freq" + listOfMaps.get(i).get(nGramKey));
            prb = (listOfMaps.get(i).get(nGramKey)-0.5)/ (countUnigrams);
            outputStream.write(nGramKey + "\n" + 
                               prb + "\n"); 
          }
          
          
          
        }
        
      }
      outputStream.write("end of probabilities");
      outputStream.close();     
      
      System.out.println("Some output for debugging: ");
      for(int i=0; i<listOfMaps.size(); i++)
      {
        Set ref = listOfMaps.get(i).keySet();;
        Iterator it = ref.iterator();
        int count10=0;
        System.out.println("for the n-grams where n equalls: " + (i+1)+
                           " we get the following first entries: ");
        while (it.hasNext()) 
        {
          if (count10==3)
            break;
          String nGramKey = (String)it.next();
          System.out.println("The ngram: " + nGramKey + " and the count: " + 
                             listOfMaps.get(i).get(nGramKey));
          count10++;
        }
      }
    }
  }
  
}
